home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / sendmail / sendmail-5.65c+IDA-1.4.4.1 / uiuc / getpath.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-01-24  |  5.1 KB  |  226 lines

  1. #include    <stdio.h>
  2. #include    <sys/types.h>
  3. #include    <sys/stat.h>
  4. #include    "path.h"
  5.  
  6. static char RCSid[] = "$Header: getpath.c,v 3.4 86/02/05 13:41:26 essick Exp $";
  7.  
  8. extern int  Debug;                    /* in mainlines */
  9.  
  10.  
  11. /*
  12.  *    char *getpath(dest) char *dest;
  13.  *
  14.  *    look in the routing tables for a path from here to that
  15.  *    specified host.  Return the path.
  16.  *    Return NULL if there is no such path.
  17.  *
  18.  *    The returned path is of the form:
  19.  *        a!b!c!d!dest!        (note trailing !)
  20.  *
  21.  *    The path is saved in a static buffer so you have to save 
  22.  *    it or it is destroyed in the next call.
  23.  *
  24.  *    A re-write of what Jeff Donnelly did a while back.
  25.  *    Ray Essick
  26.  *
  27.  *    The routing table contains lines of the form:
  28.  *    site<space>path
  29.  *        site = destination site
  30.  *        path = a!b!c!d!site!    (note trailing !)
  31.  *
  32.  *    Must be in alphabetical order since the search gives up
  33.  *    after finding a site "after" the one we want!
  34.  */
  35.  
  36. FILE * fopen ();
  37. extern char *fgets ();
  38.  
  39. static int  Dbm_Ready = 0;                /* whether init'ed */
  40. static char *PathMap = PATHTABLE;            /* path file */
  41.  
  42. char   *getpath (dest)
  43. char   *dest;
  44. {
  45.  
  46.     static char line[BUFSIZ];
  47.     FILE * mapfile;
  48.     register char  *p,
  49.                    *path;
  50.  
  51.  
  52. #ifdef    DBM
  53.     /* 
  54.      *    A version of this routine which works with the set of routines
  55.      *    described in dbm(3x).
  56.      *
  57.      *    Assumes that someone else is keeping the path tables correctly
  58.      *    updated (e.g., does a re-build on the table).
  59.      */
  60.     {
  61.     struct datum    contents;            /* returning to him */
  62.     struct datum    key;                /* fetch on this */
  63.  
  64.     if (!Dbm_Ready)
  65.     {
  66.         if (dbminit (PathMap) < 0)            /* failed */
  67.         goto hardway;                /* try manually */
  68.         Dbm_Ready++;                /* mark ready */
  69.     }
  70.     key.dptr = dest;                /* build fetch key */
  71.     key.dsize = strlen (dest) + 1;
  72.  
  73.     contents = fetch (key);                /* grab it */
  74.     if (contents.dptr == (char *) NULL)
  75.         goto checkstamps;                /* try again */
  76.     if (contents.dsize == 0)            /* empty! */
  77.         return "";                    /* convert to null string */
  78.     return (contents.dptr);                /* give him the path */
  79.     }
  80.  
  81. checkstamps:                         /* failure above */
  82.     /* 
  83.      * check the time stamps and complain if they are outdated
  84.      * so that someone will fix them. If they are correct,
  85.      * then we should merely return failure
  86.      */
  87.     {
  88.     char    name[1024];
  89.     struct stat stat1,
  90.                 stat2;
  91.  
  92.     sprintf (name, "%s.dir", PathMap);        /* db file */
  93.     if (stat (name, &stat1) < 0)            /* no db file */
  94.         goto hardway;                /* force it */
  95.     if (stat (name, &stat2) < 0)            /* no raw file */
  96.         return (char *) NULL;
  97.     if (stat1.st_mtime >= stat2.st_mtime)        /* current */
  98.     {
  99.         return (char *) NULL;
  100.     }
  101.     else
  102.     {
  103.         /* 
  104.          * could do something about a message to inform
  105.          * somebody that the database is out of date
  106.          */
  107.     }
  108.     }
  109.  
  110. hardway:                         /* failure above */
  111.     /* 
  112.      * no database or out of date  Do it by hand
  113.      * and very s...l...o...w...l...y
  114.      *
  115.      * This algorithm should really do some sort of binary
  116.      * search...
  117.      */
  118. #endif    DBM
  119.  
  120.     if ((mapfile = fopen (PathMap, "r")) == NULL)
  121.     return ((char *) NULL);                /* no file */
  122.  
  123.     while (fgets (line, BUFSIZ, mapfile) != NULL)
  124.     {
  125.     p = line;
  126.     path = NULL;
  127.     do
  128.     {
  129.         switch (*p)
  130.         {
  131.         case ' ': 
  132.         case '\t':                 /* zap and mark path */
  133.             if (path == NULL)            /* only once */
  134.             {
  135.             *p++ = '\0';
  136.             path = p;
  137.             }
  138.             else
  139.             p++;                /* gotta move over it */
  140.             break;
  141.  
  142.         case '\n': 
  143.             *p = '\0';                /* end of it all */
  144.             break;
  145.  
  146.         default: 
  147.             p++;
  148.             break;
  149.         }
  150.     }
  151.     while (*p);                    /* terminates after newline */
  152.     if (strcmp (line, dest) == 0)            /* matches */
  153.     {
  154.         break;                    /* jump and return */
  155.     }
  156.  
  157.     if (strcmp (line, dest) > 0)            /* past it */
  158.     {
  159.         path = NULL;
  160.         break;
  161.     }
  162.     }
  163.     fclose (mapfile);                    /* don't litter */
  164.     return (path);                    /* and our answer */
  165. }
  166.  
  167. /*
  168.  *    setpathfile(name)
  169.  *    char *name;
  170.  *
  171.  *    set the DBM file used by the getpath routine to something
  172.  *    else. Close one if already open.
  173.  */
  174.  
  175. setpathfile (name)
  176. char   *name;
  177. {
  178.     extern char *strsave ();
  179.     if (Dbm_Ready)
  180.     {
  181.     Dbm_Ready = 0;
  182.     /* 
  183.      * -ldbm makes no provision for closing the database
  184.      */
  185.     }
  186.     PathMap = strsave (name);                /* save it */
  187. }
  188.  
  189. struct findpath_f  *findpath (name)
  190. char   *name;
  191. {
  192.     register char  *partial;
  193.     register char  *original;
  194.     register char  *path;
  195.     register int    fullroute;
  196.  
  197.     static struct findpath_f    results;
  198.     char       *strsave(),
  199.            *index();
  200.  
  201.     if (name == (char *) NULL)
  202.     return (struct findpath_f *) NULL;
  203.     original = partial = strsave (name);
  204.     path = (char *) NULL;
  205.     fullroute = 1;
  206.     while (partial && *partial)
  207.     {
  208.     path = getpath (partial);            /* probe for a path */
  209.     if (Debug)
  210.         fprintf (stderr, "Route to %s is %s\n",
  211.             partial,
  212.             path == (char *) NULL ? "(null)" : path);
  213.     if (path != (char *) NULL)            /* good - break */
  214.         break;
  215.     partial++;                    /* skip current dot */
  216.     partial = index (partial, '.');            /* scan for dot */
  217.     fullroute = 0;                    /* no longer complete */
  218.     }
  219.     if (path == (char *) NULL)
  220.     return (struct findpath_f *) NULL;        /* nothing */
  221.     results.fp_path = strsave (path);
  222.     results.fp_matched = strsave (partial);
  223.     results.fp_fullroute = fullroute;
  224.     return (&results);
  225. }
  226.